# MicroPico plugins

from machine import Pin
import uos
import utime
import time
import network, ntptime
import socket
import machine
import boot
#------------------------------------------------------------------------------
# 启动WiFi
def start_WiFi():
    wlan = None
    try:
        wlan = network.WLAN(network.STA_IF)
        if wlan.isconnected():
            wlan.disconnect()
        wlan.active(True)
    except Exception as e:
        print(e)
    return wlan

# 断开WiFi
def stop_WIFI(wlan):
    try:
        if wlan.isconnected():
            wlan.disconnect()
        wlan.active(False)
    except Exception as e:
        print(e)

# 连接WiFi
def connect_WIFI(wlan, ip:str='', key:str=''):
    if str != '' and key != '':
        wlan.connect(ip, key)
        while not wlan.isconnected():
            utime.sleep(1)
        print('network config: ', wlan.ifconfig())
        # wlan.isconnected()
    
def scan_WIFI(wlan):
    try:
        networks = wlan.scan()   #list
        # 打印扫描结果
        for ssid, bssid, channel, rssi, authmode, hidden in networks:
            print("SSID: %s, Channel: %d, RSSI: %d" % (ssid.decode(), channel, rssi))
            # ssid password in boot.py
            if ssid.decode() == 'IOT':
                print("Connect to WiFi: ", ssid.decode())
                connect_WIFI(wlan, 'IOT', boot.ssid['IOT'])
                return True
            if ssid.decode() == 'xhz':
                print("Connect to WiFi: ", ssid.decode())
                connect_WIFI(wlan, 'xhz', boot.ssid['xhz'])
                return True
            if ssid.decode() == 'zhx':
                print("Connect to WiFi: ", ssid.decode())  
                connect_WIFI(wlan, 'zhx', boot.ssid['zhx'])
                return True
    except Exception as e:
        print(e)
    return None
#------------------------------------------------------------------------------
html = """<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>配置参数页面</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: auto;
            padding: 20px;
        }
        form {
            display: flex;
            flex-direction: column;
        }
        label {
            margin-top: 10px;
        }
        input[type="text"], select {
            margin-top: 5px;
        }
        button {
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <h1>配置参数</h1>
    <form action="/submit-config" method="post">
        <label for="username">用户名:</label>
        <input type="text" id="username" name="username" required>

        <label for="theme">主题:</label>
        <select id="theme" name="theme">
            <option value="light">浅色</option>
            <option value="dark">深色</option>
        </select>

        <label for="notifications">通知:</label>
        <input type="checkbox" id="notifications" name="notifications">

        <button type="submit">保存配置</button>
    </form>
</body>
</html>
"""

'''
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>SimpleConfigurableWebpage</title><!--引入BootstrapCSS--><linkhref="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css"rel="stylesheet"><!--引入TinyMCE--><scriptsrc="https://cdn.tiny.cloud/1/no-api-key/tinymce/6/tinymce.min.js"referrerpolicy="origin"></script><script>//初始化TinyMCEtinymce.init({selector:'#textEditor',plugins:'link image code'});functionsaveConfig(){constdata={singleChoice:document.querySelector('input[name="singleChoice"]:checked').value,multiChoices:Array.from(document.querySelectorAll('input[name="multiChoices"]:checked')).map(i=>i.value),dropdown:document.getElementById('dropdown').value,textContent:tinymce.activeEditor.getContent()};console.log(data);//这里可以将data发送到服务器进行保存}</script></head><body><divclass="container mt-5"><h2>ConfigurationForm</h2><form><!--单选按钮--><divclass="mb-3"><labelfor="singleChoice">SingleChoice:</label><br><inputtype="radio"id="option1"name="singleChoice"value="Option 1"><labelfor="option1">Option1</label><br><inputtype="radio"id="option2"name="singleChoice"value="Option 2"><labelfor="option2">Option2</label></div><!--多选框--><divclass="mb-3"><labelfor="multiChoices">MultiChoices:</label><br><inputtype="checkbox"id="choiceA"name="multiChoices"value="Choice A"><labelfor="choiceA">ChoiceA</label><br><inputtype="checkbox"id="choiceB"name="multiChoices"value="Choice B"><labelfor="choiceB">ChoiceB</label></div><!--下拉菜单--><divclass="mb-3"><labelfor="dropdown">Dropdown:</label><selectid="dropdown"class="form-select"><optionvalue="Option 1">Option1</option><optionvalue="Option 2">Option2</option></select></div><!--文本编辑器--><divclass="mb-3"><labelfor="textEditor">TextEditor:</label><textareaid="textEditor"rows="5"></textarea></div><!--保存按钮--><buttontype="button"class="btn btn-primary"onclick="saveConfig()">Save</button></form></div></body></html>
'''

'''
html2 = """<html><head> <title>ESP Web Server</title> <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="data:,"> <style>html{font-family: Helvetica; display:inline-block; margin: 0px auto; text-align: center;}
  h1{color: #0F3376; padding: 2vh;}p{font-size: 1.5rem;}.button{display: inline-block; background-color: #e7bd3b; border: none; 
  border-radius: 4px; color: white; padding: 16px 40px; text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}
  .button2{background-color: #4286f4;}</style></head><body> <h1>ESP Web Server</h1> 
  <p>GPIO state: <strong>""" + gpio_state + """</strong></p><p><a href="/?led=on"><button class="button">ON</button></a></p>
  <p><a href="/?led=off"><button class="button button2">OFF</button></a></p></body></html>"""
'''

'''
request:

GET / HTTP/1.1

Host: 192.168.50.213

Connection: keep-alive

Cache-Control: max-age=0

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7

Accept-Encoding: gzip, deflate

Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
'''

   
# 设置Socket并监听
def create_server():
    print('create socket')
    # 获取本地IP地址和端口号
    addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]

    # 创建socket对象
    s = socket.socket()

    # 绑定地址和端口
    s.bind(addr)
    
    # 开始监听连接
    s.listen(5)
    print('listening')
    
    return s

pins = [machine.Pin(i, machine.Pin.IN) for i in (0, 2, 4, 5, 12, 13, 14, 15)]
# 处理HTTP请求
def listen_connect(s):
    while True:
        cl, addr = s.accept()
        print('client connected from', addr)
        
        
def handle_get(cl, addr):
    try:
        cl_file = cl.makefile('rwb', 0)
        while True:
            line = cl_file.readline()
            print(line)
            # ['GET', '/', 'HTTP/1.1\r\n']
            if line.startswith(b'GET '):
                request = line.decode('utf-8')
                _line = request.split(' ') 
            
            if not line or line == b'\r\n':
                break
        rows = ['<tr><td>%s</td><td>%d</td></tr>' % (str(p), p.value()) for p in pins]
        response = html + '\n'.join(rows)
        cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
        cl.send(response)
        cl.close()
        
        
        
    except Exception as e:
        print(e)

import select
def handle_poll(serversocket):
    # 将服务器socket设置为非阻塞模式
    serversocket.setblocking(False)
    '''
    object <module 'select'> is of type module
        __name__ -- select
        select -- <function>
        poll -- <function>
        POLLIN -- 1
        POLLOUT -- 4
        POLLERR -- 8
        POLLHUP -- 16
        
    object <poll> is of type poll
        register -- <function>
        unregister -- <function>
        modify -- <function>
        poll -- <function>
        ipoll -- <function>
    
    events = poller.poll(1)
    help(event)
    object [] is of type list
        append -- <function>
        clear -- <function>
        copy -- <function>
        count -- <function>
        extend -- <function>
        index -- <function>
        insert -- <function>
        pop -- <function>
        remove -- <function>
        reverse -- <function>
        sort -- <function>
    '''
    # 创建一个select.poll对象
    poller = select.poll()
    poller.register(serversocket, select.POLLIN)

    # 存储已连接的客户端
    connections = {}
    addresses = {}

    try:
        while True:
            events = poller.poll()  # 等待可读事件
            for fileno, event in events:
                if fileno == serversocket:
                    conn, addr = serversocket.accept()
                    conn.setblocking(False)
                    poller.register(conn, select.POLLIN)
                    connections[fileno] = conn
                    addresses[fileno] = addr
                if event & select.POLLIN:
                    # 已连接客户端发送数据
                    client = connections[fileno]
                    data = client.recv(1024)
                    if data:
                        print("Received %s from %s" % (data.decode(), str(addresses[fileno])))
                        # 处理数据或发送响应
                        response = "HTTP/1.0 200 OK\n\nHello, World!"
                        client.sendall(response.encode())
                    else:
                        # 客户端断开连接
                        print("Connection closed from %s" % str(addresses[fileno]))
                        poller.unregister(fileno)
                        connections[fileno].close()
                        del connections[fileno]
                        del addresses[fileno]
                else:
                    print(fileno)
    except KeyboardInterrupt:
        print("\nServer stopped.")
    finally:
        # 清理
        serversocket.close()
        
def run():
    print("start esp8266")
    wlan = start_WiFi()
    if wlan != None:
        scan_WIFI(wlan)
    
    if wlan.isconnected():
        sock = create_server()
        listen_connect(sock)
       
    print("end esp8266")
        
run()
    

